/*
实验5-6 修理牧场
分数 25
作者 DS课程组
单位 浙江大学

农夫要修理牧场的一段栅栏，他测量了栅栏，发现需要 n 块木头，每块木头长度为整数 li​ 个长度单位，于是他购买了一条很长的、能锯成 n 块的木头，即该木头的长度是 li​ 的总和。

但是农夫自己没有锯子，请人锯木的酬金跟这段木头的长度成正比。为简单起见，不妨就设酬金等于所锯木头的长度。例如，要将长度为 20 的木头锯成长度为 8、7 和 5 的三段，第一次锯木头花费 20，将木头锯成 12 和 8；第二次锯木头花费 12，将长度为 12 的木头锯成 7 和 5，总花费为 32。如果第一次将木头锯成 15 和 5，则第二次锯木头花费 15，总花费为 35（大于 32）。

请编写程序帮助农夫计算将木头锯成 n 块的最少花费。
输入格式:

输入首先给出正整数 n（≤10^4），表示要将木头锯成 n 块。第二行给出 n 个正整数（≤50），表示每段木块的长度。
输出格式:

输出一个整数，即将木头锯成 n 块的最少花费。

输入样例:

8
4 5 1 2 1 3 1 1

输出样例:

49
*/

#include <iostream>
#include <queue>

using namespace std;

/*
核心思想是每次选择当前最小的两段木头进行锯切，以确保每次锯切的花费最小，从而使得总花费最小。
这个过程类似于哈夫曼编码的构建过程，因此可以保证最优解。
*/
int main() {
    int n;
    cin >> n;
    priority_queue<int, vector<int>, greater<int>> q;
    for (int i = 0; i < n; i++) {
        int x;
        cin >> x;
        q.push(x);
    }
    int ans = 0;
    while (q.size() > 1) {
        int a = q.top();
        q.pop();
        int b = q.top();
        q.pop();
        ans += a + b;
        q.push(a + b);
    }
    cout << ans << endl;
    return 0;
}